-- MoonSaberAnnouncer.lua

-- This addon watches the unfiltered combat log and announces them via
-- scrolling combat text. Currently, deaths, buffs, and debuffs are
-- tracked. Buff and debuff messages are intentionally similar to
-- built-in messages for the player, but with lighter colors.

-- The unfiltered combat log events are monitored now. Performance can
-- probably be improved by using combat log filters.

-- these tables contain all the auras (buffs/debuffs) being
-- tracked. most auras are listed by name, but ids are also supported
-- to handle name collisions.

local aura_ids = {}
local aura_names = {}

aura_names["Aspect of the Pack"] = true
aura_names["Banish"] = true
aura_names["Bestial Wrath"] = true
aura_names["Blind"] = true
aura_names["Charge"] = true
aura_names["Cheap Shot"] = true
aura_names["Concussive Shot"] = false
aura_names["Counterattack"] = true
aura_names["Curse of Doom"] = true
aura_names["Cyclone"] = true
aura_names["Dazed"] = false
aura_names["Death Coil"] = true
aura_names["Deterrence"] = true
aura_names["Disarm"] = true
aura_names["Divine Shield"] = true
aura_names["Drunken Haze"] = true
aura_names["Fear"] = true
aura_names["Feral Charge Effect"] = true
aura_names["Freezing Trap Effect"] = true
aura_names["Gouge"] = true
aura_names["Howl of Terror"] = true
aura_names["Ice Block"] = true
aura_names["Improved Concussive Shot"] = true
aura_names["Improved Wing Clip"] = true
aura_names["Intercept Stun"] = true
aura_names["Intimidating Shout"] = true
aura_names["Kidney Shot"] = true
aura_names["Paralyzing Poison"] = true
aura_names["Petrify"] = true
aura_names["Polymorph"] = true
aura_names["PVP Trinket"] = true
aura_names["Prowl"] = true
aura_names["Sap"] = true
aura_names["Scatter Shot"] = true
aura_names["Seduction"] = true
aura_names["Shadowmeld"] = true
aura_names["Shoulder Charge"] = true
aura_names["Sleep"] = true
aura_names["Stealth"] = true
aura_names["The Beast Within"] = true
aura_names["Viper Sting"] = true
aura_names["War Stomp"] = true
--aura_names["Wyvern Sting"] = true -- this catches sleep and DoT

aura_ids[27068] = true -- Wyvern Sting sleep

------------------------------------------------------------
-- utility functions ---------------------------------------
------------------------------------------------------------

local function check_friendly(flags)
  return bit.band(flags, COMBATLOG_OBJECT_REACTION_FRIENDLY) ~= 0
end

local function check_hostile(flags)
  return bit.band(flags, COMBATLOG_OBJECT_REACTION_HOSTILE) ~= 0
end

local function score_friendly(flags)
  if check_friendly(flags) then
    return 1
  else
    return -1
  end
end

------------------------------------------------------------
-- main functions ------------------------------------------
------------------------------------------------------------

function MoonSaberAnnouncer_CombatText(m, score)
  local r, g, b
  
  if score > 0 then
    r = 0.5
    g = 1.0
    b = 0.5
  else
    r = 1.0
    g = 0.5
    b = 0.5
  end

  CombatText_AddMessage(m, CombatText_StandardScroll, r, g, b)
end 

function MoonSaberAnnouncer_OnEvent(self, event, ...)
  -- using naming conventions at http://www.wowwiki.com/API_COMBAT_LOG_EVENT
  -- as of 2008-08-02

  if event == "COMBAT_LOG_EVENT_UNFILTERED" then
    
    local timestamp = arg1
    local subevent = arg2
    local sourceGUID = arg3
    local sourceName = arg4
    local sourceFlags = arg5
    local destGUID = arg6
    local destName = arg7
    local destFlags = arg8
    
    -- skip messages about current player
    if destName == UnitName("player") then
      return
    end

    -- skip messages about pets
    --if string.sub(destGUID, 5, 5) == "4" then
    --  return
    --end

    -- skip messages about guardians. these include the vipers from snake traps.
    if bit.band(destFlags, COMBATLOG_OBJECT_TYPE_GUARDIAN) ~= 0 then
      return
    end

    -- check if friendly or hostile unit
    local friendly = score_friendly(destFlags)

    -- finally respond to interesting events

    if subevent == "UNIT_DIED" then
      if friendly > 0 then
        CombatText_AddMessage(format("%s died", destName), CombatText_StandardScroll, 0.125, 0.000, 0.000)
      else
        CombatText_AddMessage(format("%s died", destName), CombatText_StandardScroll, 0.000, 0.125, 0.000)
      end
    end

    if subevent == "SPELL_AURA_APPLIED" then
      extraSpellId = arg9
      extraSpellName = arg10
      extraSpellSchool = arg11
      auraType = arg12

      if aura_names[extraSpellName] or aura_ids[extraSpellId] then
        local score = nil
        if auraType == "BUFF" then
          score = 1
        elseif auraType == "DEBUFF" then
          score = -1
        else
          score = 0
        end
        score = score * friendly

        MoonSaberAnnouncer_CombatText(format("<%s/%s>", destName, extraSpellName), score)
      end
    end

    if subevent == "SPELL_AURA_REMOVED" then
      extraSpellId = arg9
      extraSpellName = arg10
      extraSpellSchool = arg11
      auraType = arg12

      if aura_names[extraSpellName] or aura_ids[extraSpellId] then
        local score = nil
        if auraType == "BUFF" then
          score = 1
        elseif auraType == "DEBUFF" then
          score = -1
        else
          score = 0
        end
        score = score * friendly

        MoonSaberAnnouncer_CombatText(format("<%s/%s> fades", destName, extraSpellName), score)
      end
    end
  end
end

local frame = CreateFrame("Frame", "MoonSaberAnnouncerFrame");
frame:SetScript("OnEvent", MoonSaberAnnouncer_OnEvent);
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
